package com.sun.co;

import com.huaban.analysis.jieba.JiebaSegmenter;
import com.huaban.analysis.jieba.SegToken;
import com.huaban.analysis.jieba.WordDictionary;
import com.kennycason.kumo.CollisionMode;
import com.kennycason.kumo.WordCloud;
import com.kennycason.kumo.WordFrequency;
import com.kennycason.kumo.bg.CircleBackground;
import com.kennycason.kumo.font.KumoFont;
import com.kennycason.kumo.font.scale.SqrtFontScalar;
import com.kennycason.kumo.nlp.FrequencyAnalyzer;
import com.kennycason.kumo.nlp.tokenizers.ChineseWordTokenizer;
import com.kennycason.kumo.palette.LinearGradientColorPalette;
import com.qianxinyao.analysis.jieba.keyword.Keyword;
import com.qianxinyao.analysis.jieba.keyword.TFIDFAnalyzer;
import org.junit.jupiter.api.Test;

import java.awt.*;
import java.io.*;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class Main {


    /**
     * 官网测试
     */
    @Test
    public void main() {
        JiebaSegmenter segmenter = new JiebaSegmenter();
        String[] sentences =
                new String[]{"这是一个伸手不见五指的黑夜。我叫孙悟空，我爱北京，我爱Python和C++。", "我不喜欢日本和服。", "雷猴回归人间。",
                        "工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作", "结果婚的和尚未结过婚的"};
        for (String sentence : sentences) {
            System.out.println(segmenter.process(sentence, JiebaSegmenter.SegMode.INDEX).toString());
        }
    }

    /**
     * 官网测试2
     * tfidf算法提取关键词
     */
    @Test
    public void main2() {
        //String content="孩子上了幼儿园 安全防拐教育要做好";
        String content = "孙孙孙孙孙文祥";
        int topN = 5;
        TFIDFAnalyzer tfidfAnalyzer = new TFIDFAnalyzer();
        List<Keyword> list = tfidfAnalyzer.analyze(content, topN);
        for (Keyword word : list) {
            System.out.println(word.getName() + ":" + word.getTfidfvalue() + ",");
        }
        // 防拐:0.1992,幼儿园:0.1434,做好:0.1065,教育:0.0946,安全:0.0924
    }

    /**
     * 字典测试
     */
    @Test
    public void main3() throws IOException {

        // 获取高频词
        List<Keyword> hfWord = getHFWord(50);
        // 生成词云
        List<WordFrequency> wordFrequencyList = new LinkedList<>();
        hfWord.forEach(a -> {
            WordFrequency wordFrequency = new WordFrequency(a.getName(), (int)a.getTfidfvalue());
            wordFrequencyList.add(wordFrequency);
        });
        cloud(wordFrequencyList);
        // 将高频词单独取出组成set
        Set<String> collect = hfWord.stream().map(a -> a.getName()).collect(Collectors.toSet());
        // 获取分词
        List<SegToken> participleArray = getParticipleArray();
        // 过滤，只需要高频词的分词信息
        List<SegToken> hfParticipleArray = participleArray.stream().filter(a -> collect.contains(a.getWord())).collect(Collectors.toList());
        // 共现图分析
        List<CoC> coCList = new LinkedList<>();
        // 计算
        analysis(coCList, hfParticipleArray, participleArray);



        coCList.forEach(a -> {
            System.out.println(a.getKeyWord() + "," + a.getDesKeyWord() + "," + a.getNum());
        });


    }

    /**
     * 生成词云
     */
    private void cloud(List<WordFrequency> wordFrequencies) throws IOException {
        //建立词频分析器，设置词频，以及词语最短长度，此处的参数配置视情况而定即可
        FrequencyAnalyzer frequencyAnalyzer = new FrequencyAnalyzer();
        frequencyAnalyzer.setWordFrequenciesToReturn(600);
        frequencyAnalyzer.setMinWordLength(2);

        //引入中文解析器
        frequencyAnalyzer.setWordTokenizer(new ChineseWordTokenizer());
        //指定文本文件路径，生成词频集合
        //List<WordFrequency> wordFrequencyList = frequencyAnalyzer.load("/wordcloud.txt");
        //设置图片分辨率
        Dimension dimension = new Dimension(1920, 1080);
        //此处的设置采用内置常量即可，生成词云对象
        WordCloud wordCloud = new WordCloud(dimension, CollisionMode.PIXEL_PERFECT);
        //设置边界及字体
        wordCloud.setPadding(2);
        java.awt.Font font = new java.awt.Font("STSong-Light", 2, 20);
        //设置词云显示的三种颜色，越靠前设置表示词频越高的词语的颜色
        wordCloud.setColorPalette(new LinearGradientColorPalette(Color.RED, Color.BLUE, Color.GREEN, 30, 30));
        wordCloud.setKumoFont(new KumoFont(font));
        //设置背景色
        wordCloud.setBackgroundColor(new Color(255, 255, 255));
        //设置背景图片
        //wordCloud.setBackground(new PixelBoundryBackground("E:\\爬虫/google.jpg"));
        // 设置背景图层为圆形
        wordCloud.setBackground(new CircleBackground(255));
        wordCloud.setFontScalar(new SqrtFontScalar(12, 45));
        //生成词云
        wordCloud.build(wordFrequencies);
        wordCloud.writeToFile("C:/Users/sunwx/Desktop/wy.png");
    }

    /**
     * 计算相邻的
     *
     * @param coCList
     * @param hfParticipleArray
     * @param participleArray
     */
    private void analysis(List<CoC> coCList, List<SegToken> hfParticipleArray, List<SegToken> participleArray) {
        // 对高频词循环
        hfParticipleArray.forEach(a -> {
            // 获取相邻的左分词,最短为2
            List<SegToken> collect = participleArray.stream().filter(b -> (a.startOffset - b.getEndOffset() < 5) && (a.startOffset - b.getEndOffset() >= 0) && (b.getWord().length() > 1)).collect(Collectors.toList());
            collect.forEach(c -> {
                CoC d = new CoC();
                d.setKeyWord(c.getWord());
                d.setDesKeyWord(a.getWord());
                d.setNum(d.getNum() + 1);
                coCList.add(d);
            });
            // 获取相邻的右分词
            List<SegToken> collect2 = participleArray.stream().filter(b -> (b.getStartOffset() - a.getEndOffset() < 5) && (b.getStartOffset() - a.getEndOffset() >= 0) && (b.getWord().length() > 1)).collect(Collectors.toList());
            collect.forEach(c -> {
                CoC d = new CoC();
                d.setKeyWord(a.getWord());
                d.setDesKeyWord(c.getWord());
                d.setNum(d.getNum() + 1);
                coCList.add(d);
            });
        });
    }


    /**
     * 获取分词数组
     *
     * @return
     * @throws IOException
     */
    private List<SegToken> getParticipleArray() throws IOException {
        WordDictionary instance = WordDictionary.getInstance();
        String fileString = getFileString();
        JiebaSegmenter segmenter = new JiebaSegmenter();
        List<SegToken> process = segmenter.process(fileString, JiebaSegmenter.SegMode.INDEX);
        // 去除不需要的分词
        List<SegToken> collect = process.stream().filter(a -> instance.containsWord(a.getWord())).collect(Collectors.toList());
        // System.out.println(collect);
        return collect;
    }


    /**
     * 统计出前topN高频词
     */
    private List<Keyword> getHFWord(Integer topN) throws IOException {
        String fileString = getFileString();

        TFIDFAnalyzer tfidfAnalyzer = new TFIDFAnalyzer();
        List<Keyword> list = tfidfAnalyzer.analyze(fileString, topN);
        return list;
    }

    /**
     * 获取文件字符串
     */
    public String getFileString() throws IOException {
        BufferedReader gbk = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/1.txt"), "GBK"));
        String line = null;
        StringBuffer f = new StringBuffer();
        while ((line = gbk.readLine()) != null) {
            f.append(line.trim());
        }
        return f.toString();
    }

}
